package configuration

import (
	"encoding/json"
	"fmt"
	"kop/modules/configuration/client"
	serverC "kop/modules/server/client"
	"kop/pb/service"
	"kop/util/log"
	"sync"
	"time"
)

func init() {

	var data []DiamondShopConf
	if err := json.Unmarshal(client.Load("DiamondShop"), &data); err != nil {
		panic(err)
	}

	for _, v := range data {

		switch v.Type {
		case 1:

			diamondShopList1 = append(diamondShopList1, v)

		case 2:

			diamondShopList2 = append(diamondShopList2, v)
		}
	}

	log.Info("Load DiamondShop.json success.")

	//------------------------------------------------------------------------------------------------------

	res, err := serverC.GetServers()
	if err != nil {
		panic(err)
	}

	for _, v := range res {
		servers[v.ServerID] = v
	}
}

const (
	Z8 = 28 // 开服28天
)

type (

	// 钻石商店
	DiamondShopConf struct {
		ID       int32 // 索引
		Type     uint8 // 开始类型
		BeginDay int   // 开始天数
		EndDay   int   // 结算天数
		ShopID   int32 // 限购商店

		bTime time.Time
		eTime time.Time
	}

	DiamondShopList []DiamondShopConf
	//ActivityValueList []ActivityValueConf
)

func (c DiamondShopConf) BeginTime() time.Time {

	return c.bTime
}

func (c DiamondShopConf) EndTime() time.Time {

	return c.eTime
}

// 是否正常活动期间
func (c DiamondShopConf) InTime() bool {

	return time.Now().Sub(c.EndTime()) <= 0
}

func (c *DiamondShopConf) setTime1(serverID int32) {

	var n = 开服第N天(serverID)

	var year, month, day = time.Now().Date()
	var t = time.Date(year, month, day, 0, 0, 0, 0, time.Local)

	c.bTime = t.Add(time.Duration(-(n - c.BeginDay)) * time.Hour * 24)
	c.eTime = t.Add(time.Hour*22 + time.Duration(c.EndDay-n)*time.Hour*24)
}

func (c *DiamondShopConf) setTime2(serverID int32) {

	var n = 开服第N天(serverID) // 开服第X天
	n -= Z8

	if n <= 0 {
		panic("(c *DiamondShopList) setTime2: n <= 0")
	}

	var mod = n % Z8
	if mod == 0 {
		mod = Z8
	}

	var year, month, day = time.Now().Date()
	var t = time.Date(year, month, day, 0, 0, 0, 0, time.Local)

	c.bTime = t.Add(time.Duration(-(mod - c.BeginDay)) * time.Hour * 24)
	c.eTime = t.Add(time.Hour*22 + time.Duration(c.EndDay-mod)*time.Hour*24)
}

// 开服28天内的
func (c DiamondShopList) GetOne1(serverID int32) (DiamondShopConf, bool) {

	var n = 开服第N天(serverID) // 开服第X天

	if n <= Z8 {
		// open server not over 28 day
		for _, v := range c {
			if n <= v.EndDay {
				//v.ServerID = serverID
				v.setTime1(serverID)
				return v, true
			}
		}
	}

	return DiamondShopConf{}, false
}

// 开服28天后的
func (c DiamondShopList) GetOne2(serverID int32) DiamondShopConf {

	var n = 开服第N天(serverID) // 开服第X天
	n -= Z8

	var endDay = c[len(c)-1].EndDay
	var mod = n % endDay
	if mod == 0 {
		mod = endDay
	}
	for _, v := range c {
		if mod <= v.EndDay {
			v.setTime2(serverID)
			//v.ServerID = serverID
			return v
		}
	}

	panic(fmt.Sprintf("activity [%d] configs err", c[0].Type))
}

var (
	lock    sync.Mutex
	servers = make(map[int32]*service.Server)

	diamondShopList1 DiamondShopList // 开服X日的
	diamondShopList2 DiamondShopList // 循环的

)

func 开服时间(serverID int32) time.Time {

	if server, ok := servers[serverID]; ok {

		var year, month, day = time.Unix(server.Timestamp.Seconds, 0).Date()
		return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
	}

	lock.Lock()
	lock.Unlock()

	var res, _ = serverC.GetServers()
	for _, v := range res {
		servers[v.ServerID] = v
		if v.ServerID == serverID {

			var year, month, day = time.Unix(v.Timestamp.Seconds, 0).Date()
			return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
		}
	}

	panic(fmt.Errorf("server[%d] not found", serverID))
}

func 开服第N天(serverID int32) int {

	return int(time.Now().Sub(开服时间(serverID)).Hours())/24 + 1
}

func GetDiamondShop(serverID int32) DiamondShopConf {

	if conf, ok := diamondShopList1.GetOne1(serverID); ok {
		return conf
	} else {
		return diamondShopList2.GetOne2(serverID)
	}
}
